/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.dx.dex.code;

import com.android.dx.rop.code.RegisterSpec;
import com.android.dx.rop.code.RegisterSpecList;
import com.android.dx.rop.code.RegisterSpecSet;
import com.android.dx.rop.code.SourcePosition;

/**
 * Pseudo-instruction which is used to hold a snapshot of the state of local
 * variable name mappings that exists immediately after the instance in an
 * instruction array.
 */
public final class LocalSnapshot extends ZeroSizeInsn {

	/** {@code non-null;} local state associated with this instance */
	private final RegisterSpecSet locals;

	/**
	 * Constructs an instance. The output address of this instance is initially
	 * unknown ({@code -1}).
	 * 
	 * @param position
	 *            {@code non-null;} source position
	 * @param locals
	 *            {@code non-null;} associated local variable state
	 */
	public LocalSnapshot(SourcePosition position, RegisterSpecSet locals) {
		super(position);

		if (locals == null) {
			throw new NullPointerException("locals == null");
		}

		this.locals = locals;
	}

	/** {@inheritDoc} */
	@Override
	public DalvInsn withRegisterOffset(int delta) {
		return new LocalSnapshot(getPosition(), locals.withOffset(delta));
	}

	/** {@inheritDoc} */
	@Override
	public DalvInsn withRegisters(RegisterSpecList registers) {
		return new LocalSnapshot(getPosition(), locals);
	}

	/**
	 * Gets the local state associated with this instance.
	 * 
	 * @return {@code non-null;} the state
	 */
	public RegisterSpecSet getLocals() {
		return locals;
	}

	/** {@inheritDoc} */
	@Override
	protected String argString() {
		return locals.toString();
	}

	/** {@inheritDoc} */
	@Override
	protected String listingString0(boolean noteIndices) {
		int sz = locals.size();
		int max = locals.getMaxSize();
		StringBuffer sb = new StringBuffer(100 + sz * 40);

		sb.append("local-snapshot");

		for (int i = 0; i < max; i++) {
			RegisterSpec spec = locals.get(i);
			if (spec != null) {
				sb.append("\n  ");
				sb.append(LocalStart.localString(spec));
			}
		}

		return sb.toString();
	}
}
